#include <iostream>
#include <cstdio>
#include <memory>
#include <vector>
#include <string>
#include "HttpServer.hpp"
#include "Err.hpp"
#include "Log.hpp"
#include "Utility.hpp"

//当用户用浏览器访问'/'根目录时，我们不能把整个文件夹里面的内容都给他，存在一个主页面页面
//假设访问根目录的子目录，也要给他一个子目录的主页面
static const std::string webroot = "./wwwroot";
static const std::string defaulthHomePage = "index.html";

const std::string SEP = "\r\n";

class HttpRequst
{
public:
    HttpRequst() : path_(webroot)
    {
    }
    ~HttpRequst() {}
    void Print()
    {
        logMessage(Debug,"method_:%s url_:%s httpversion_:%s",method_.c_str(),url_.c_str(),httpversion_.c_str());
        logMessage(Debug,"path_:%s",path_.c_str());
        logMessage(Debug,"suffix_:%s",suffix_.c_str());

    }
public:
    std::string method_;
    std::string url_;
    std::string httpversion_;
    std::vector<std::string> headerbody_;
    std::string path_;
    std::string suffix_;
};
HttpRequst Deserialize(std::string &requst)
{
    HttpRequst hr;
    std::string line = Utility::ReadLine(requst, SEP);
    Utility::ReadOneLine(line, &hr.method_, &hr.url_, &hr.httpversion_);
    hr.path_ += hr.url_;
    if(hr.path_[hr.path_.size()-1] == '/') hr.path_ += defaulthHomePage;

    auto pos = hr.path_.rfind('.');  //获取后缀：C++、html和Css语言需要根据后缀进行解析
    if(pos != std::string::npos)
    {
        hr.suffix_ = hr.path_.substr(pos);
    }
    while (!requst.empty())
    {
        size_t pos = requst.find(SEP);
        hr.headerbody_.push_back(requst.substr(0, pos));
        requst.erase(0, pos + SEP.size());
    }
    return hr;
}
std::string GetSuffix(const std::string& suffix)
{
      std::string context;
      if(suffix == ".html" || suffix == ".htm") context += "text/html";
      else if(suffix == ".css") context += "text/css";
      else if(suffix == ".js") context += "application/x-javascript";
      else if(suffix == ".png") context += "image/png";
      else if(suffix == ".jpg") context += "image/jpeg";
      else if(suffix == ".ico") context += "application/x-ico";
      else {}
      return context + SEP;
}
std::string HandlResponse(std::string &requst)
{
    // 对请求进行处理
    std::cout << "-----------------------" << std::endl;
    //std::cout << requst << std::endl;
    // std::string body = "<html><body><h1>This is title</h1><p>This is paragraph</p></body></html>";
    // std::string body = "<html><body style=""background-color:yellow""><h2 style=""background-color:red"">This is a heading</h2><p style=""background-color:green"">This is a paragraph.</p></body></html>";

    HttpRequst hr = Deserialize(requst);
    hr.Print();
    std::string body;
    Utility::ReadFile(hr.path_, &body);
    // 响应
    std::string response = "HTTP/1.0 200 OK" + SEP; // 状态行
    response += "Content-Length: " + std::to_string(body.size()) + SEP; //报头行
    response += GetSuffix(hr.suffix_);    
    response += SEP;        // 空行
    response += body + SEP; // 有效载荷

    return response;
}

void Usage(std::string u)
{
    std::cout << "usage:\n\t" << u << " serverport" << std::endl;
}
int main(int argv, char *argc[])
{
    if (argv != 2)
    {
        Usage(argc[0]);
        exit(USAGE_ERROR);
    }
    uint16_t port = atoi(argc[1]);
    std::unique_ptr<HttpServer> upts(new HttpServer(HandlResponse, port));
    upts->InitServer();
    upts->Start();
    return 0;
}